#ifndef _MISC_
#define _MISC_

#include <math.h>
#include <string>

#define PI 3.14159265359f

#ifndef MAX_LINE_SIZE
	#define MAX_LINE_SIZE 10240
#endif

#ifndef INT
	int Integer(float32 a)
	{
		return a;
	}
	int Integer(double a)
	{
		return a;
	}
	#define INT(x) Integer(x)
#endif
#ifndef FLOAT
	float32 Float(int a)
	{
		return a;
	}
	float32 Float(double a)
	{
		return a;
	}
	#define FLOAT(x) Float(x)
#endif

// Mathematic formula for rotate a point from origin.
// Useful to rotate quads by an angle.
b2Vec2 RotateFromOrigin(b2Vec2 origin, b2Vec2 point, float32 Radian)
{
	if(Radian == 0)
		return point;
	if(origin == point)
		return point;
	b2Vec2 newpos = b2Vec2_zero;
	newpos.x = origin.x + (point.x - origin.x) * cosf(Radian) - (point.y - origin.y) * sinf(Radian);
	newpos.y = origin.y + (point.x - origin.x) * sinf(Radian) + (point.y - origin.y) * cosf(Radian);
	return newpos;
}
// Radian to Sexagesimal function.
// Internal b2box angles are radian, but I converted all to sexagesimal.
// Also RotateFromOrigin uses radian.
float32 RadianToSexagesimal(float32 Radian)
{
	float32 result = Radian * 180 / PI;
	int loops = INT(result / 360);
	result -= loops * 360;
	return result;
}
// Sexagesimal To Radian function.
float32 SexagesimalToRadian(float32 Sexagesimal)
{
	int loops = INT(Sexagesimal / 360);
	Sexagesimal -= loops * 360;
	return (Sexagesimal * PI) / 180;
}

// Manage of files.
int GetFileRealPosition(FILE * f)
{
	return f->_ptr - f->_base;
}
void SetFileRealPosition(FILE * f, __int64 pos)
{
	f->_ptr = f->_base + pos;
}
// Get one line 
char * GetFileLine(FILE * f,int npos = - 1)
{
	int pos = npos, first = 0, last = 0;
	if (pos < 0)
		pos = GetFileRealPosition(f);
	char c = 0;
	if(f->_base == NULL)
		fgetc(f);
	while((c != EOF)&&(c != '\n'))
	{
		c = f->_base[pos];
		pos++;
	}
	pos--;
	last = pos;
	c = 0;
	while((c != '\n')&&(pos > 0))
	{
		pos--;
		c = f->_base[pos];
	}
	first = (pos > 0) ? pos + 1 : 0;
	static char Line[MAX_LINE_SIZE];
	memcpy(Line,&f->_base[first],last - first);
	Line[last - first] = '\0';
	SetFileRealPosition(f,last + 1);	
	return Line;
}
// Get one line and ignore comments (#)
char * GetLineIgnoreComments(FILE * f, int npos = -1)
{
	char * Line = GetFileLine(f,npos); 
	while (Line[0] == '#')
	{
		strcpy(Line,GetFileLine(f));	
	}
	return Line;

}
// Delayed Calling a function.
class DelayedFunction
{
public:
	bool (*Reiteration)(float32);
	void (*Function)(void*);
	float32 TimeLeft;
	void * UserMessage;
	DelayedFunction()
	{
		Reiteration = 0;
		Function = 0;
		TimeLeft = 0;
	}	

	void Start(float32 time = 0, bool (*reiteration)(float32) = NULL, void (*function)(void*) = NULL, void * UMsg = NULL)
	{
		if (TimeLeft > 0)
			return;
		if(time > 0)
			TimeLeft = time;
		if(reiteration != NULL)
			Reiteration = reiteration;
		if(function != NULL)
			Function = function;
		if(UMsg != NULL)
			UserMessage = UMsg;
		Run(0);
	}
	bool Run(float32 time)
	{
		if (TimeLeft <= 0)
			return false;
		TimeLeft -= time;
		if (Reiteration != NULL)
			if (Reiteration(time))
				TimeLeft = 0;
		if (TimeLeft <= 0)
			if (Function != NULL)
				Function(UserMessage);
		return true;
	}
	void Stop(){TimeLeft = 0;}
};
// Get Mouse position.
b2Vec2 GetMousePosition()
{
	if (!hge->Input_IsMouseOver())
		return b2Vec2(-1,-1);
	b2Vec2 r;
	hge->Input_GetMousePos(&r.x,&r.y);
	r.y = GAME_HEIGHT - r.y;
	return r;
}
// Get the n byte of a DWORD
bool GetBit(DWORD dw, int n = 1)
{
	if (n < 1)
		return false;
	if (n > sizeof(DWORD) * 8)
		return false;
	DWORD cmp = 255 - INT(pow(DWORD(2),n - 1.0));
	cmp = dw | cmp;
	return (cmp == 255);
}
bool BitIn(DWORD a, DWORD bit)
{
	if ( a == bit )
		return true;
	if (bit == 0)
		return !GetBit(a,1);
	if (a == 0)
		return false;
	int posbit = 1;
	while(!GetBit(bit,posbit))
		posbit++;
	return GetBit(a,posbit) == GetBit(bit,posbit);
}
// Find a character in a string
int strfind(const char * _s,char _c)
{
	int size = strlen(_s);
	for (int i = 0;i<size;i++)
	{
		if(_c == _s[i])
			return i;
	}
	return -1;
}
// Return a string from a char
char * CharToString(char c)
{
	static char result[2];
	result[0] = c;
	result[1] = '\0';
	return result;
}
const char * FloatToString(float32 _f, char * buffer)
{
	if(_f == 0.0f)
		return "0";
	int decimals,sign;
	std::string _buffer = _fcvt(_f,4,&decimals,&sign);
	if (_buffer.length() == 0)
		return "0";
	if(decimals > 0)
		_buffer.insert(decimals,".");
	else if(decimals < 0)
		while(decimals < 0)
		{
			_buffer.insert(0,"0");
			decimals++;
		}
	if (decimals == 0)
		_buffer.insert(0,"0.");
	if(sign)
		_buffer.insert(0,"-");
	strcpy(buffer,_buffer.c_str());
	return (const char*)buffer;
}
#endif
